﻿namespace Trader.Analyzing
{
    using System;
    using System.Collections.Generic;
    using Interface;

    public class Scenario : IScenario
    {
        private readonly List<IRange> ranges;

        public Scenario(List<IRange> ranges)
        {
            this.ranges = ranges;
        }

        #region IScenario Members

        public bool ExactOccurance(IList<decimal> occurance)
        {
            if (ranges.Count != occurance.Count)
            {
                return false;
            }

            for (int i = 0; i < ranges.Count; i++)
            {
                if (!ranges[i].IsInRange(occurance[i]))
                {
                    return false;
                }
            }

            return true;
        }

        public decimal? GetValuePerDay(IList<decimal> values)
        {
            if (values.Count >= ranges.Count)
            {
                return null;
            }

            for (int i = 0; i < values.Count; i++)
            {
                if (!ranges[i].IsInRange(values[i]))
                {
                    return null;
                }
            }

            IRange maxRange = ranges[values.Count];
            int maxDay = values.Count;

            for (int i = values.Count + 1; i < ranges.Count; i++)
            {
                if (maxRange.CompareTo(ranges[i]) < 0)
                {
                    maxRange = ranges[i];
                    maxDay = i;
                }
            }

            decimal valuePerDay = (maxRange.Mid - values[values.Count - 1])/(maxDay - values.Count + 1);
            return valuePerDay;
        }

        public decimal GetExpectedGain()
        {
            decimal maxMid = ranges[1].Mid;
            for (int i = 2; i < ranges.Count; i++)
            {
                maxMid = Math.Max(maxMid, ranges[i].Mid);
            }

            return maxMid;
        }

        public decimal GetMaxNegativaChange()
        {
            decimal maxNegativeChange = 0;
            for (int i = 1; i < ranges.Count; i++)
            {
                maxNegativeChange = Math.Min(maxNegativeChange, ranges[i].Mid/ranges[i - 1].Mid - 1);
            }

            return Math.Abs(maxNegativeChange);
        }

        #endregion
    }
}